#pragma once


////////////////////////////////////////////////////////
//

struct CBitmap{
	HBITMAP hBm;
	int Width;
	int Height;
	CBitmap(){hBm =0; Width = Height = 0;}
};

#define nLAYOUT		3
#define MaxLayout_Idx		2

class CBeauty: public AnimaObj{
public:
	int ScrX;
	virtual void Draw();
};

class BackGround
{
	BKG_ID BmId;
	//Bm[0] is the most front and the largest layout;
	CBitmap Bm[nLAYOUT]; //layouts
	BYTE nLayout;

	CBeauty* pBeauty;
	BYTE nBeauty;

	//Speed[0] for the speed of the front layout. 
	//Speed[1.. nLAYOUT] are relatived moving speed of other layouts
	float Speed[nLAYOUT];// when Layout 0  moves  Speed[i] pixels,  layout[i] moves 1 pixels
	int Ext[nLAYOUT];
	int OffsetX[nLAYOUT];
	int L0Moved;
private:
	void MoveOffset(int  LayoutId_i, int& Pixel_io);
public:
	bool IsWindowReachEdge( );
	int GetMaxGkWidth(){return Bm[0].Width;}
	int GetGkOffsetX(){return OffsetX[0];}
	void Load(BKG_ID BkId_i);
	void Move(int nPixel_i);
	void Draw();
	void Unload();

	BackGround();
};

////////////////////////////////////////////////////////
//basic action was hard coding:
//

struct Action{
	ACT_ID ActId;

	Action(BYTE Aid_i):ActId(Aid_i){}
	Action( ):ActId(0x10){ }
};

typedef std::pair<void*, Action*> MapAid;
typedef std::map<KEY_ID, MapAid> KeyCombo;
typedef std::map<KEY_ID, Action*> UniAction;
typedef std::queue<KEY_ID> KeyChain;
typedef std::map<KEY_ID, MapAid>::iterator PKC;

class ComboAction{
	UniAction UA;
	KeyCombo* pKC;
	std::queue<void*> AllKC;
	KeyCombo*  NewKeyCombo();

public:
	void InsertKeys(KeyChain& ks_io, Action* ActId2Pic);
	Action* MatchKey(KeyCombo*& pkc_io, KEY_ID k_i); //retrun Action ID

	void DeleteCombos();
	ComboAction(){ pKC = new KeyCombo();}
	~ComboAction(){delete pKC; DeleteCombos();}
};



////////////////////////////////////////////////////////
#define HITBOUND		15
#define COBOUNDS		20
#define COBOUNDB		30
#define ALPHA		10
#define MOVE 10
#define GROUND		20

class Fighter;
class CombatSystem;

class ActionPic : public AnimaObj{
	friend class Fighter;
	friend class CombatSystem;
	int HalfWidth;//for the picture
	std::vector<POSITION> HitPt;
	std::vector<int> TopPt; //the height of the picture...X will figure out by other way
	std::vector<int> Head2Top; //Height for body, collision detection.
public:
	int HitValue;
	int GetTopPt(){return TopPt[NowFrame -1];}
	int GetFootPt(){return TopPt[NowFrame -1] + Height;}
	int GetHeadPt(){return TopPt[NowFrame -1] + Head2Top[NowFrame-1];}
	int GetHead2Top(){return Head2Top[NowFrame-1];}
	const POSITION& GetHitPt(){return HitPt[NowFrame-1];}

	int  XAcc;
	//POSITION JointPt;
	virtual void Draw();

	void Load(int id_i, int nFrame_i){ AnimaObj::Load(id_i, nFrame_i);  HalfWidth = Width / 2; XAcc = 0;}


};


typedef std::map<ACT_ID, ActionPic*>::iterator PA2P;
class Fighter
{
	friend class CombatSystem;
	FTR_ID FtrId;
	PLR_ID PlayerId;
	int HP;//health point;

private:
	std::map<ACT_ID, ActionPic*> ActId2Pic;
	KeyCombo* pkc;
	ActionPic* pActPic;

private:
	bool PerformingUninterrupt;
	bool IsInterruptAction(ACT_ID aid_i);
	void LoadFighterInfo();
	ACT_ID GetActIdByInput();
	void BkPos2ScrPos();

private://for positioning.
	ACT_ID CurrentAct;
	bool FaceRight;
	int X;//the middle
	int Y;//the top
	RECT HitRect;
	RECT CoRect;
	bool RightActDir;
	UINT ScrOffsetX;
	ComboAction CA;//
public:
	void CalculateRect(int X_i, RECT& HitRect_o, RECT& Rect_o);
	void Load(PLR_ID PlayerId_i, FTR_ID FighterId_i);
	ACT_ID SetAction();
	void Draw();
	void Unload();
	Fighter();
};
////////////////////////////////////////////////////////
class HPShower{
	friend class CombatSystem;
	HBITMAP Bar;
	int Width;
	int Height;
	int X[2], Y;
private:
	float HP[2];
	int Lose[2];
public:
	HPShower();
	~HPShower();
	void Draw( );
};

////////////////////////////////////////////////////////
////overall controlling?
inline bool Intersect(const POSITION& P_i, const RECT& R_i){
	if(P_i.x > R_i.left && P_i.x < R_i.right && P_i.y > R_i.top && P_i.y < R_i.bottom) return true;
	return false;
}

class CombatSystem
{
private://elements:
	const static BYTE nP	= 2; //not likely will be changed..
	const static BYTE MaxPlr_Idx = 1;
	BackGround BK;
	Fighter PlrFtr[nP];
	HPShower ShowHP;
	bool WasBeenHitting[nP];
	PLR_ID FirstHit;
	BYTE Mark[nP];
	PLR_ID Winner;
	
private://initiate:
	std::vector<Action>UniAction;
	void InitiateUniAction();
	void InitiatePlrFtrsBasicAction();

private:
	bool IntersectFtr(PLR_ID id_i);
	bool IntersectWindow(PLR_ID id_i); //using KEY_ID to express which edge

private://position-testing data structure
	int X[nP];
	int Y[nP];
	RECT FCoRect[nP];
	RECT HitRect[nP];
	RECT OutLeft;
	RECT OutRight;
	void ChangeXY(PLR_ID id_i);
	void ChangePostionByCD();
	void DontChangeX(PLR_ID id_i);
	void Face2Face();
	void MoveWindow();
	void MakeOutterRects();
	void MakeTestRects();
	bool IdWasHit(PLR_ID id_i);
	bool CheckWin();

public://regular functions
	void LoadAll(FTR_ID F1Id_i, FTR_ID F2Id_i);
	void NewCombat();
	void Draw();
	void UnloadAll();
	void AutoSetPosition();

	CombatSystem();
	~CombatSystem();

private://debug info
	void ShowRects();

};




